<!-- 实体模型 -->
<script lang="ts" setup>
import type { EntityTableData, PageTableRequestData, SevenCodeItem } from "@@/apis/entity/type.ts"
import type { FormInstance, TabsPaneContext } from "element-plus"
import { parseSearchDate } from "@/common/utils/datetime"
import { deleteEntityDataApi, getByTypeApplicabilityApi, searchClassifyApi, searchEntityDataApi } from "@@/apis/entity"
import { usePagination } from "@@/composables/usePagination"
import { Delete, Loading, Refresh, Search, View } from "@element-plus/icons-vue"
import { ElMessage, ElMessageBox } from "element-plus"
import { computed, nextTick, onMounted, onUnmounted, ref } from "vue"
import { useRouter } from "vue-router"
import ScenarioCard from "./components/ScenarioCard.vue"
import { useAutoRefresh } from "@/layouts/composables/useAutoRefresh";
import TabSelectedScroll from "@@/components/TabSelectedScroll/index.vue"
import TabSelectedPopover from "@@/components/TabSelectedPopover/index.vue"

defineOptions({
  // 命名当前组件
  name: "EntityIndex"
})

const router = useRouter()
const countryOptions = ref<SevenCodeItem[]>([])
const isGrid = ref<boolean>(true)
const searchFormRef = ref<FormInstance | null>(null)
const searchKey = ref()
const loading = ref<boolean>(false)
const tableData = ref<EntityTableData[]>([])
const multipleSelection = ref<EntityTableData[]>([])
const TableRef = ref()
const { paginationData } = usePagination()

paginationData.pageSize = 20

// 无限滚动状态
const isLoading = ref(false)
const hasMoreData = ref(true)

// 获取标签
const tabData = ref<Record<string, number>>({})
function searchAndClassify() {
  const params = buildRequestParams()
  searchClassifyApi(params).then((res: any) => {
    tabData.value = res.data
    console.log(res,'res.data');

  })
}

// 计算属性：选中的ID列表
const selectedId = computed(() => {
  if (multipleSelection.value?.length > 0) {
    return multipleSelection.value.map(item => item.id)
  }
  return []
})

// 搜索表单数据
const searchData = reactive<PageTableRequestData>({
  code: undefined,
  country: undefined,
  createTime: undefined,
  endTime: undefined,
  timeRange: undefined,
  current: 0,
  pageSize: 20,
  tags: []
})

// 修改卡片容器引用
const cardScrollContainer = ref()
const isCardLoading = ref(false)

// 重置搜索条件
function resetSearch() {
  searchKey.value = ""
  searchData.tags = ["全部"]
  searchFormRef.value?.resetFields()
  handleSearch()
}

// 获取表格数据（首次加载或搜索）
function getTableData() {
  // 重置状态
  hasMoreData.value = true
  paginationData.currentPage = 1

  const params = buildRequestParams()

  loading.value = true
  return searchEntityDataApi(params)
    .then(({ data }) => {
      // 检查是否还有更多数据
      hasMoreData.value = data.rows.length >= paginationData.pageSize

      // 更新表格数据
      tableData.value = data.rows
      paginationData.total = data.total
    })
    .catch(() => {
      tableData.value = []
      hasMoreData.value = false
    })
    .finally(() => {
      loading.value = false
      // 检查是否需要立即加载更多
      checkAndLoadMore()
    })
}

// 构建请求参数
function buildRequestParams() {
  const params: PageTableRequestData = {
    pageSize: paginationData.pageSize,
    current: paginationData.currentPage,
    code: searchData.code,
    tags: searchData.tags,
    country: searchData.country,
    createTime: searchData.createTime,
    endTime: searchData.endTime,
    searchKey: searchKey.value
  }

  // 处理时间范围
  if (searchData.timeRange && searchData.timeRange.length == 2) {
    params.createTime = searchData.timeRange[0]
    params.endTime = parseSearchDate(searchData.timeRange[1])
  }

  return params
}

watch(
  () => isGrid.value,
  () => {
    checkAndLoadMore()
  }
)

// 检查并加载更多数据（如果内容不足以滚动）
function checkAndLoadMore() {
  if (!isGrid.value) {
    nextTick(() => {
      const scrollContainer = TableRef.value?.$el.querySelector(".el-scrollbar__wrap")
      const contentContainer = TableRef.value?.$el.querySelector(".el-scrollbar__view")

      if (scrollContainer && contentContainer) {
        // 判断是否需要加载更多数据
        const isScrollable = (scrollContainer.scrollHeight < scrollContainer.clientHeight || contentContainer.clientHeight < scrollContainer.scrollHeight)

        if (isScrollable && hasMoreData.value) {
          // 手动加载更多数据
          loadData()
        }
      }
    })
  } else {
    nextTick(() => {
      cardScrollContainer.value = document.querySelector(".custom-card-container")
      const isScrollable = cardScrollContainer.value.scrollHeight > cardScrollContainer.value.clientHeight
      if (!isScrollable && hasMoreData.value) {
        loadData()
      }
    })
  }
}

function searchByTags() {
  getTableData();
  searchAndClassify()
}

// 搜索处理
function handleSearch() {
  if (paginationData.currentPage === 1) {
    getTableData()
    searchAndClassify()
  } else {
    paginationData.currentPage = 1
    getTableData()
    searchAndClassify()
  }
}

// 获取国家/地区选项
function getCountryOptions() {
  getByTypeApplicabilityApi({ type: "country" }).then(({ data }) => {
    countryOptions.value = data
  })
}

// 实体详情或创建
function handleCreateTask() {
  router.replace({ name: "EntityCreate" })
}

// 表格行选择变化
function handleSelectionChange(val: EntityTableData[]) {
  multipleSelection.value = val
}

// 批量删除
function handleMultipleDelete() {
  if (!multipleSelection.value.length) return

  const ids = multipleSelection.value.map(item => item.id as string)
  const names = multipleSelection.value.map(item => item.code)

  confirmDelete(names.join("，"), () => {
    deleteEntityDataApi(ids).then(() => {
      ElMessage.success("删除成功")
      hanldeClearSelection()
      getTableData()
    })
  })
}

// 清除选择
function hanldeClearSelection() {
  nextTick(() => {
    TableRef.value?.clearSelection()
  })
}

// 获取行键
function getRowKeys(row: EntityTableData) {
  return row.id
}

// 删除单个实体
function handleDelete(row: EntityTableData) {
  if (!row.id) return
  confirmDelete(row.code, () => {
    deleteEntityDataApi([row.id]).then(() => {
      ElMessage.success("删除成功")
      hanldeClearSelection()
      getTableData()
    })
  })
}

// 删除确认
function confirmDelete(name: string, callback: () => void) {
  ElMessageBox.confirm(`正在删除实体模型：${name}，确认删除？`, "提示", {
    confirmButtonText: "确定",
    cancelButtonText: "取消",
    type: "warning"
  }).then(callback)
}

// 查看详情
function handleView(row: EntityTableData) {
  router.replace({ name: "EntityView", query: { id: row.id } })
}

// 切换选择
function handleToggleSelect(row: EntityTableData) {
  TableRef.value?.toggleRowSelection(row, undefined, false)
}

// 添加卡片滚动处理函数
function handleCardScroll() {
  if (!cardScrollContainer.value || !isGrid.value) return

  const {
    scrollTop,
    scrollHeight,
    clientHeight
  } = cardScrollContainer.value

  // 当距离底部 100px 时触发加载
  if (scrollHeight - scrollTop - clientHeight <= 100) {
    loadData()
  }
}
useAutoRefresh(handleSearch)
// 修改 onMounted 钩子，确保正确获取卡片容器
onMounted(() => {
  getCountryOptions()
  handleSearch()

  // 为表格添加滚动监听
  nextTick(() => {
    const tableScrollContainer = TableRef.value?.$el.querySelector(".el-scrollbar__wrap")
    if (tableScrollContainer) {
      tableScrollContainer.addEventListener("scroll", () => {
        const scrollDistance = tableScrollContainer.scrollHeight - tableScrollContainer.scrollTop - tableScrollContainer.clientHeight
        if (scrollDistance <= 100) {
          loadData()
        }
      })
      // 检查内容高度并加载更多数据
      checkAndLoadMore()
    }

    cardScrollContainer.value = document.querySelector(".custom-card-container")
    if (cardScrollContainer.value) {
      cardScrollContainer.value.addEventListener("scroll", handleCardScroll)
    }
  })
})

// 修改 loadData 函数，确保返回 Promise
function loadData() {
  // 防止重复加载
  if (isLoading.value || !hasMoreData.value) {
    return Promise.resolve()
  }

  isLoading.value = true
  paginationData.currentPage++

  const params = buildRequestParams()

  return searchEntityDataApi(params)
    .then(({ data }) => {
      // 检查是否还有更多数据
      hasMoreData.value = data.rows.length >= paginationData.pageSize

      // 追加新数据
      tableData.value = [...tableData.value, ...data.rows]

      // 更新总数
      paginationData.total = data.total
    })
    .catch((error) => {
      console.error("加载失败:", error)
      hasMoreData.value = false
    })
    .finally(() => {
      isLoading.value = false
      checkAndLoadMore()
      return Promise.resolve()
    })
}

// 无限滚动配置
const infiniteScrollConfig = {
  // 距离底部多少像素时触发加载
  distance: 100,
  // 是否禁用
  disabled: computed(() => isLoading.value || !hasMoreData.value),
  // 立即检查
  immediate: true
}

onUnmounted(() => {
  if (cardScrollContainer.value) {
    cardScrollContainer.value.removeEventListener("scroll", handleCardScroll)
  }
})
</script>

<template>
  <div class="app-container pager-container">
    <div class="cc-search">
      <div class="cc-search-common">
        <el-form ref="searchFormRef" :model="searchData" size="large" :inline="true" @keyup.enter="handleSearch">
          <el-form-item prop="country" label="名称">
            <el-input v-model="searchKey" placeholder="请输入" @keydown.enter="handleSearch" />
          </el-form-item>
          <el-form-item prop="country" label="国别/地区">
            <el-select
              v-model="searchData.country" clearable placeholder="请选择" style="width: 240px"
              @change="handleSearch()"
            >
              <el-option
                v-for="item in countryOptions" :key="item.value" :label="item.name"
                :value="item.value"
              />
            </el-select>
          </el-form-item>
          <el-form-item>
            <el-button :icon="Search" type="primary" @click="handleSearch">
              搜索
            </el-button>
            <el-button :icon="Refresh" @click="resetSearch">
              重置
            </el-button>
          </el-form-item>
        </el-form>
      </div>
    </div>
    <div v-loading="loading" class="content-other">
      <div class="mb-main-padding toolbar">
        <div class="flex-y-center tag">
          <el-button type="primary" @click="handleCreateTask">
            新建实体
          </el-button>
          <el-button
            :disabled="multipleSelection.length < 1" type="danger"
            @click="handleMultipleDelete"
          >
            批量删除
          </el-button>
        </div>
        <div class="flex-y-center sh-operate">
          <div class="tab">
            <TabSelectedPopover v-model:selecteds="searchData.tags" :data="tabData" @change="searchByTags" />
          </div>
          <div class="sh-btn" :class="{ active: isGrid }" @click="() => isGrid = true">
            <el-tooltip content="卡片" placement="bottom">
              <SvgIcon name="table-grid" />
            </el-tooltip>
          </div>
          <div class="sh-btn" :class="{ active: !isGrid }" @click="() => isGrid = false">
            <el-tooltip content="列表" placement="bottom">
              <SvgIcon name="table-list" />
            </el-tooltip>
          </div>
        </div>
      </div>
      <div v-show="isGrid" class="cpi-content-main">
        <div
          class="custom-card-container"
          ref="cardScrollContainer"
          v-infinite-scroll="loadData"
          :infinite-scroll-disabled="infiniteScrollConfig.disabled"
          :infinite-scroll-distance="infiniteScrollConfig.distance"
          :infinite-scroll-immediate="infiniteScrollConfig.immediate"
        >
          <template v-for="(item, index) in tableData" :key="index">
            <ScenarioCard
              :data="item"
              :selected="selectedId.includes(item.id)"
              @handle-delete="handleDelete"
              @handle-view="handleView"
              @toggle-select="handleToggleSelect"
            />
          </template>
          <div class="card-loading-indicator">
            <div v-if="isLoading" class="loading-more">
              <el-icon class="is-loading">
                <Loading />
              </el-icon>
              <span>加载中...</span>
            </div>
            <div v-else-if="hasMoreData" class="loading-more">
              <i class="fas fa-angle-double-down el-icon" />
              <span>下拉加载更多数据...</span>
            </div>
            <div v-else-if="!hasMoreData && tableData.length > 0" class="no-more-data">
              <span>没有更多数据了</span>
            </div>
            <div v-else-if="tableData.length === 0" class="no-data">
              <span>暂无数据</span>
            </div>
          </div>
        </div>
      </div>
      <div v-show="!isGrid" class="cpi-content-main">
        <el-auto-resizer>
          <template #default="{ height, width }">
            <el-table
              :height="height"
              v-el-table-infinite-scroll="loadData"
              @selection-change="handleSelectionChange"
              ref="TableRef"
              v-loading="loading"
              :data="tableData"
              :row-key="getRowKeys"
            >
              <el-table-column type="selection" header-align="left" :reserve-selection="true" width="55" />
              <el-table-column prop="code" label="名称" header-align="left" />
              <el-table-column prop="name" label="别名" header-align="left" />
              <el-table-column prop="entityType.country" label="国别/地区" header-align="left">
                <template #default="{ row }">
                  {{ row.entityTypeText.country }}
                </template>
              </el-table-column>
              <el-table-column prop="entityType.category" label="类别" header-align="left">
                <template #default="{ row }">
                  {{ row.entityTypeText.category }}
                </template>
              </el-table-column>
              <el-table-column prop="description" label="描述" show-overflow-tooltip header-align="left" />
              <el-table-column fixed="right" label="操作" align="center" width="140">
                <template #default="scope">
                  <el-space :size="12">
                    <el-link :underline="false" @click.stop v-throttle="() => handleView(scope.row)" title="查看">
                      <el-icon :size="18">
                        <View />
                      </el-icon>
                    </el-link>
                    <el-link :underline="false" type="danger" @click.stop v-throttle="() => handleDelete(scope.row)" title="删除">
                      <el-icon :size="18">
                        <Delete />
                      </el-icon>
                    </el-link>
                  </el-space>
                </template>
              </el-table-column>
              <!-- 添加底部加载指示器 -->
              <template #append>
                <div v-if="isLoading || hasMoreData" class="loading-more">
                  <el-icon class="is-loading">
                    <Loading />
                  </el-icon>
                  <span>加载更多...</span>
                </div>
                <div v-else-if="tableData.length > 0" class="no-more-data">
                  <span>没有更多数据了</span>
                </div>
              </template>
            </el-table>
          </template>
        </el-auto-resizer>
      </div>
    </div>
  </div>
</template>

<style lang="scss" scoped>
@import "@@/assets/styles/main-page.scss";
@import "@@/assets/styles/mixins.scss";

.cc-search-common {
  .el-form-item--large {
    margin-bottom: 0px !important;
  }
}

.toolbar {
  display: flex;
  flex-direction: row;
  justify-content: space-between;
}

.sh-operate {
  flex: 1;
  display: flex;
  flex-direction: row;
  justify-content: flex-end;
  overflow: hidden;
  .tab {
    flex: 1;
    overflow: hidden;
    display: flex;
    justify-content: flex-end;
  }
}

.custom-card-container {
  $border-color: #223448;
  height: 100%;
  width: 100%;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
  gap: 20px;
  padding: 5px 10px 0px 0 !important;
}

.custom-card-container > * {
  min-width: 0;
}

.pager-container {
  padding-bottom: 20px !important;
}

.loading-more,
.no-more-data {
  height: 40px;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #909399;
  font-size: 14px;

  .el-icon {
    margin-right: 8px;
  }
}

.no-more-data {
  color: #c0c4cc;
}

/* 修改卡片视图的加载指示器样式 */
.card-loading-indicator {
  grid-column: 1 / -1;
  height: 50px;
  padding: 20px 0;
  text-align: center;
  width: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
  margin-top: 10px;

  .loading-more,
  .no-more-data,
  .no-data {
    height: 40px;
    display: flex;
    align-items: center;
    justify-content: center;
    color: #909399;
    font-size: 14px;

    .el-icon {
      margin-right: 8px;
    }
  }

  .no-more-data,
  .no-data {
    color: #c0c4cc;
  }
}

/* 优化卡片容器样式 */
.custom-card-container {
  width: 100%;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
  gap: 20px;
  padding: 10px;
  min-height: 100%; /* 确保容器至少填满父元素 */
}

@media screen and (max-width: 768px) {
  .toolbar {
    flex-direction: column;
  }
  .sh-operate {
    width: 100%;
  }
}
</style>
